package com.woniuxy.controller;

import com.baomidou.mybatisplus.core.conditions.update.Update;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.commons.exception.AccountException;
import com.woniuxy.commons.exception.LateException;
import com.woniuxy.commons.utile.BeanCopyUtil;
import com.woniuxy.commons.utile.CommonsUtil;
import com.woniuxy.controller.dto.AccountActivationDto;
import com.woniuxy.controller.dto.AccountDto;
import com.woniuxy.controller.dto.GetAllStudentDto;
import com.woniuxy.controller.dto.UserInfoDto;
import com.woniuxy.controller.form.RepairpeopleForm;
import com.woniuxy.controller.form.SetAccountForm;
import com.woniuxy.controller.form.UserLoginForm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.commons.exception.LoginPhoneException;
import com.woniuxy.commons.exception.RegisterException;
import com.woniuxy.commons.utile.Result;
import com.woniuxy.controller.form.AccountForm;
import com.woniuxy.dao.model.Account;
import com.woniuxy.service.AccountService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Keep it simple
 * @since 2022-06-28
 */
@RestController
@Api(tags = "账号信息处理接口")
@ResponseBody
@RequestMapping("/account")
public class AccountController {


    @Resource
    private AccountService accountService;

    @Resource
    private StringRedisTemplate srt;

    @ApiOperation("登录")
    @PostMapping("/login")
    public Result login(String username,String password){
        return null;
    }


    @ApiOperation("添加维修工")
    @PostMapping("/addrepair")
    @ResponseBody
    public Result Repairpeople(@Valid @RequestBody RepairpeopleForm repairpeopleForm){
        String addrepairpeople = accountService.addrepairpeople(repairpeopleForm);
        if (addrepairpeople!=null){
            return Result.instance().setCode(200).setData(addrepairpeople);
        }
        throw new LateException(1103,"添加维修工失败");
    }


    /**
     * 学生注册
     * @param accountForm
     * @return
     */
    @PostMapping("/register")
    @ApiOperation("学生账号注册")
    private Result register(@Valid @RequestBody AccountForm accountForm) throws MessagingException {
        //参数验证
        if (accountForm.getAccountEmail() == null || accountForm.getAccountEmail().equals("")) throw new LoginPhoneException(1010,"邮箱不能为空");
        if (accountForm.getAccountName() == null || accountForm.getAccountName().equals("")) throw new LoginPhoneException(1010,"用户名不能为空");
        if (accountForm.getAccountPhone() == null || accountForm.getAccountPhone().equals("")) throw new LoginPhoneException(1010,"手机号不能为空");
        if (accountForm.getPassword() == null || accountForm.getPassword().equals("")) throw new LoginPhoneException(1010,"密码不能为空");
        if (accountForm.getCode() == null || accountForm.getCode().equals("")) throw new LoginPhoneException(1010,"验证码不能为空");
        //判断该手机号是否被注册
        Account account_phone = accountService.getOne(new QueryWrapper<Account>().eq("account_phone", accountForm.getAccountPhone()));
        if (account_phone != null)throw new RegisterException(1001,"该手机号已被注册");

        //判断手机验证码
        if (accountForm.getCode()!=null || !(accountForm.getCode().equals(""))){
            String phoneCode = srt.opsForValue().get("login:phone:code:" + accountForm.getAccountPhone());
            System.out.println(phoneCode);
            if (phoneCode == null || !(phoneCode.equals(accountForm.getCode()))) throw new LoginPhoneException(1003,"验证码有误，或已失效");
        }

        //进行注册
        Account account = accountService.register(accountForm);

        return Result.instance().setCode(200).setMessage("注册成功").setData(account);
    }

    /**
     * 账号激活
     * @param activeCode
     * @return
     */
    @GetMapping("/activation")
    @ApiOperation("账号激活")
    @ApiImplicitParam(name = "activeCode",value = "注册完成后会向邮箱发激活码激活账号",required = true)
    public Result activation(String activeCode){
        if (activeCode==null || activeCode.equals(""))throw new AccountException(1011,"激活码有误");
        Account activation = accountService.getOne(new QueryWrapper<Account>().eq("account_activation", activeCode));
        if (activation==null)throw new AccountException(1011,"激活码有误");
        accountService.activation(activeCode);
        AccountActivationDto accountActivationDto = BeanCopyUtil.copyOne(activation, AccountActivationDto.class);
        return Result.instance().setCode(200).setMessage("激活成功").setData(accountActivationDto);
    }

    /**
     * 获取验证码（可用于短信验证登录   注册时判断手机号是否属于该用户）
     * @param phone
     * @return
     */
    @GetMapping("/sendCode")
    @ApiOperation("获取验证码")
    @ApiImplicitParam(name = "phone",value = "通过手机号获取验证码",required = true)
    public Result sendCode(String phone){
        if(phone==null || phone.equals("")) throw new LoginPhoneException(1004,"手机号有误");
        String s = accountService.sendCode(phone);
        return Result.instance().setMessage("验证码已发送,注意接收").setCode(200);
    }

    /**
     *
     * @param
     * @return
     */
    @GetMapping("/MailboxVerification1")
    @ApiOperation("用户修改邮箱时，会发一个邮箱验证码")
    @ApiImplicitParam(name = "email",value = "新邮箱",type = "String")
    public Result MailboxVerification1(String email) throws MessagingException {
        AccountDto accountDto = (AccountDto)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        //发激活码
        String activeCode = CommonsUtil.getActiveCode(64);
        CommonsUtil.sendMail(email,
                "邮箱验证码",
                activeCode);
        //在redis中存一个邮箱验证码过期时间120s
        srt.opsForValue().setIfAbsent("code:"+accountDto.getAccount(),activeCode,120, TimeUnit.SECONDS);
        return Result.instance().setMessage("邮箱验证已发送，注意确认").setCode(200);
    }

    /**
     * 邮箱验证
     * @param activeCode
     * @return
     */
    @GetMapping("/MailboxVerification2")
    @ApiOperation("邮箱验证,验证成功修改邮箱")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "activeCode",value = "邮箱验证码",type = "String",required = true),
            @ApiImplicitParam(name = "email",value = "新邮箱",type = "String",required = true)
    })
    public Result MailboxVerification2(String activeCode,String email){
        if (activeCode==null || activeCode.equals(""))throw new AccountException(1012,"验证码有误");
        if (email==null || email.equals(""))throw new AccountException(1012,"邮箱有误");

        AccountDto accountDto = accountService.MailboxVerification2(activeCode,email);
        return Result.instance().setCode(200).setMessage("邮箱修改成功").setData(accountDto);
    }

    /**
     * 修改信息
     * @param accountForm
     * @return
     */
    @PostMapping("/setAccount")
    @ApiOperation("修改信息")
    private Result setAccount(@Valid @RequestBody SetAccountForm accountForm) {
        if (accountForm.getAccountEmail() == null || accountForm.getAccountEmail().equals("")) throw new LoginPhoneException(1010,"邮箱不能为空");
        if (accountForm.getAccountName() == null || accountForm.getAccountName().equals("")) throw new LoginPhoneException(1010,"用户名不能为空");
        if (accountForm.getAccountPhone() == null || accountForm.getAccountPhone().equals("")) throw new LoginPhoneException(1010,"手机号不能为空");
        Account account = accountService.setAccount(accountForm);
        AccountDto accountDto = BeanCopyUtil.copyOne(account, AccountDto.class);
        return Result.instance().setCode(200).setMessage("修改成功").setData(accountDto);
    }

    /**
     * 修改用户名
     * @param accountName
     * @return
     */
    @GetMapping("/setAccountName")
    @ApiOperation("修改用户名")
    @ApiImplicitParam(name = "accountName",value = "新用户名",required = true,type = "string")
    public Result setAccountName(String accountName){
        if (accountName == null && accountName.equals(""))throw new AccountException(1013,"用户名不能空");
        AccountDto accountDto = accountService.setAccountName(accountName);
        return Result.instance().setMessage("电话修改成功").setCode(200).setData(accountDto);
    }

    /**
     * 修改电话
     * @param code Phone
     * @return
     */
    @GetMapping("/setPhone")
    @ApiOperation("修改电话")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code",value = "验证码",required = true,type = "string"),
            @ApiImplicitParam(name = "phone",value = "新电话",required = true,type = "string")
    })
    public Result setPhone(String code,String phone){
        AccountDto accountDto = accountService.setPhone(code,phone);
        return Result.instance().setMessage("电话修改成功").setCode(200).setData(accountDto);
    }

    /**
     * 修改密码
     * @param code password
     * @return
     */
    @GetMapping("/setPassword")
    @ApiOperation("修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code",value = "验证码",required = true,type = "string"),
            @ApiImplicitParam(name = "password",value = "新密码",required = true,type = "string")
    })
    public Result setPassword(String code,String password){
        AccountDto accountDto = accountService.setPassword(code,password);
        return Result.instance().setMessage("密码修改成功").setCode(200).setData(accountDto);
    }

    @GetMapping("/getAllAccepter")
    @ApiOperation("获取全部管理员信息")
    public Result getAllAccepter(){
        QueryWrapper<Account> qw = new QueryWrapper<Account>().eq("state", 0);
        List<Account> accounts = accountService.list(qw);
        List<UserInfoDto> result = BeanCopyUtil.copyList(accounts, UserInfoDto.class);
        return Result.instance().setData(result);
    }

    @GetMapping("/getAllRepairer")
    @ApiOperation("获取全部维修工信息")
    public Result getAllRepairer(){
        List<Account> states = accountService.list(new QueryWrapper<Account>().eq("state", 1));
        List<UserInfoDto> result = BeanCopyUtil.copyList(states, UserInfoDto.class);
        return Result.instance().setData(result);
    }

    @GetMapping("/getAllStudent")
    @ApiOperation("获取全部学生")
    public Result getAllStudent(Integer pageNum,Integer pageSize){
//        List<Account> states = accountService.list(new QueryWrapper<Account>().eq("state", 2));
//        List<GetAllStudentDto> result = BeanCopyUtil.copyList(states, GetAllStudentDto.class);

        Page<GetAllStudentDto> page = accountService.getAllStudent(pageNum == null  || pageNum.equals("") ? 1 : pageNum,pageNum==null || pageNum.equals("") ? 5 : pageSize);
        return Result.instance().setData(page).setCode(200).setMessage("查询成功");
    }

    @GetMapping("/setAccountState")
    @ApiOperation("管理员修改学生状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account",value = "账号",type = "String"),
            @ApiImplicitParam(name = "state",value = "状态",type = "Integer")
    })
    public Result setAccountState(String account,Integer state){
        Account account1 = accountService.getOne(new QueryWrapper<Account>().eq("account", account));
        if (account1==null)throw new RuntimeException("该学生不存在");
        UpdateWrapper<Account> wrapper = new UpdateWrapper<>();
        wrapper.set("account_state",state);
        wrapper.eq("account",account);
        boolean update = accountService.update(wrapper);
        if (!update)throw new RuntimeException("修改失败");
        return Result.instance().setCode(200).setMessage("查询成功");
    }

    @GetMapping("/errorlogin")
    @ApiOperation("未登录")
    public Result errorlogin(){
        return Result.instance().setCode(403);
    }

}

